package com.deanlib.cabinet.data.network;


import com.deanlib.cabinet.base.IPopupAuxiliary;
import com.deanlib.cabinet.data.event.UserStateEvent;
import com.deanlib.cabinet.data.network.exception.ApiException;
import com.deanlib.cabinet.data.network.exception.CustomException;
import com.deanlib.cabinet.utils.UserManager;

import org.greenrobot.eventbus.EventBus;

import java.util.Optional;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.Observer;
import io.reactivex.functions.Function;

/**
 * Created by Zaifeng on 2018/2/28.
 * Modify by Dean on 2021/6/19
 * 对返回的数据进行处理，区分异常的情况。
 */

public class ResponseTransformer {

    public static <T> ObservableTransformer<Response<T>, Optional<T>> handleResult() {
        return upstream -> upstream
                .onErrorResumeNext(new ErrorResumeFunction<>())
                .flatMap(new ResponseFunction<>());
    }

    public static <T> ObservableTransformer<Response<T>, Optional<T>> handleResult(IPopupAuxiliary popupAuxiliary) {
        return upstream -> upstream
                .onErrorResumeNext(new ErrorResumeFunction<>(popupAuxiliary))
                .flatMap(new ResponseFunction<>());
    }


    /**
     * 非服务器产生的异常，比如本地无无网络请求，Json数据解析错误等等。
     *
     * @param <T>
     */
    private static class ErrorResumeFunction<T> implements Function<Throwable, ObservableSource<? extends Response<T>>> {

        IPopupAuxiliary popupAuxiliary;

        public ErrorResumeFunction() {
        }

        public ErrorResumeFunction(IPopupAuxiliary popupAuxiliary) {
            this.popupAuxiliary = popupAuxiliary;
        }

        @Override
        public ObservableSource<? extends Response<T>> apply(Throwable throwable) throws Exception {
            ApiException apiException = CustomException.handleException(throwable);
            if (popupAuxiliary != null) {
                if (apiException.getCode() == CustomException.NETWORK_ERROR) {
                    popupAuxiliary.networkError();
                    return Observer::onComplete;
                }
            }
            return Observable.error(apiException);
        }
    }

    /**
     * 服务其返回的数据解析
     * 正常服务器返回数据和服务器可能返回的exception
     *
     * @param <T>
     */
    private static class ResponseFunction<T> implements Function<Response<T>, ObservableSource<Optional<T>>> {

        @Override
        public ObservableSource<Optional<T>> apply(Response<T> tResponse) {
            Integer code = tResponse.getCode();
            String message = tResponse.getMessage();
            if (tResponse.getSuccess()) {
                T data = tResponse.getData();
                //把消息推出去
//                    if (tResponse.getNotif() != null){
//                        EventBus.getDefault().postSticky(new NotificationEvent(tResponse.getNotif()));
//                    }
                return Observable.just(Optional.ofNullable(data));
            } else {
                handleResponseFail(tResponse);
                return Observable.error(new ApiException(code, message));
            }
        }
    }

    public static void handleResponseFail(Response response) {
        switch (response.getCode()) {
            case 22002:
                UserManager.getInstance().exit();
                EventBus.getDefault().post(new UserStateEvent());
                break;
        }
    }

}
